package com.ngc.mall.common.configure.token;

import com.auth0.jwt.exceptions.*;
import com.auth0.jwt.interfaces.Claim;
import com.ngc.mall.common.configure.LocalUser;
import com.ngc.mall.common.configure.exception.BusinessException;
import com.ngc.mall.common.configure.response.ResponseCode;
import com.ngc.mall.domain.UserDomain;
import com.ngc.mall.service.IUserService;
import com.ngc.mall.util.DoubleJWT;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@Component
public class AuthorizeVerifyResolverImpl implements AuthorizeVerifyResolver{

    @Resource
    private DoubleJWT jwt;

    @Resource
    private IUserService userService;

    @Override
    public Boolean handleLogin(HttpServletRequest request, HttpServletResponse response) {
        String tokenStr = verifyHeader(request);
        Map<String, Claim> claims = null;
        try {
            claims = jwt.decodeAccessToken(tokenStr);
        } catch (TokenExpiredException e) {
            System.out.println("token过期");
//            throw BusinessException.PERMISSION_NO_ACCESS;
            throw new BusinessException(ResponseCode.USER_NOT_LOGGED_IN);
        } catch (AlgorithmMismatchException | SignatureVerificationException | JWTDecodeException | InvalidClaimException e) {
            System.out.println("token不合法");
//            throw BusinessException.PERMISSION_NO_ACCESS;
            throw new BusinessException(ResponseCode.UNKNOWN);
        }
        return getClaim(claims);
    }

    @Override
    public void handleAfterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        // 记住：很重要，请求结束后，一定要清理 ThreadLocal 中的用户信息
        LocalUser.clearLocalUser();
    }

    private Boolean getClaim(Map<String,Claim> claims){
        if (claims == null) {
//            throw new TokenInvalidException(10041);
            System.out.println("token不合法");
//            throw BusinessException.PERMISSION_NO_ACCESS;
            throw new BusinessException(ResponseCode.USER_NOT_LOGGED_IN);
        }
        Long identity = claims.get("identity").asLong();
        UserDomain user = userService.getById(identity);
        if (user == null) {
//            throw new NotFoundException(10021);
            System.out.println("未找到该用户");
//            throw BusinessException.PERMISSION_NO_ACCESS;
            throw new BusinessException(ResponseCode.USER_NOT_LOGGED_IN);
        }
        LocalUser.setLocalUser(user);
        return true;
    }
    private String verifyHeader(HttpServletRequest request) {
        // 处理头部header,带有access_token的可以访问
        String authorization = request.getHeader("Authorization");
        if (authorization == null || Strings.isBlank(authorization)) {
//            System.out.println("无访问权限");
//            throw BusinessException.PERMISSION_NO_ACCESS;
            throw new BusinessException(ResponseCode.USER_NOT_LOGGED_IN);
        }
        String[] splits = authorization.split(" ");
        final int tokenSplitLen = 2;
//        if (splits.length != tokenSplitLen) {
//            throw new AuthorizationException(10013);
//        }
        // Bearer 字段
        String scheme = splits[0];
        // token 字段
        String tokenStr = splits[1];
//        if (!Pattern.matches(BEARER_PATTERN, scheme)) {
//            throw new AuthorizationException(10013);
//        }

        return tokenStr;
    }
}
